package com.webzavod.controllers;

import com.webzavod.json.OrderJSON;
import com.webzavod.model.Book;
import com.webzavod.model.Order;
import com.webzavod.services.BookService;
import com.webzavod.services.OrderService;
import com.webzavod.services.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: v.tsapaev
 * Date: 25.05.12
 * Time: 19:07
 * To change this template use File | Settings | File Templates.
 */
@Controller
@RequestMapping("/app")
public class ApplicationController {

    private static Logger LOG = LoggerFactory.getLogger(ApplicationController.class);

    @Autowired
    BookService bookService;

    @Autowired
    OrderService orderService;

    @Autowired
    UserService userService;

    /**
     * main page show book list
     * @param model - standart spring param
     * @return main page view
     */
    @RequestMapping(value = "/main", method = RequestMethod.GET)
    public String main(Model model) {
        LOG.info("/main");
        List<Book> bookList = bookService.getAllBooks();
        LOG.info("bookList = " + bookList);
        model.addAttribute("bookList", bookList);
        return "jsp/app/index";
    }

    /**
     * this method called when user change count book
     * @param correctOrder is fake. This help to transfer new book list data
     * @param request standart webapp param
     * @return correct actual order
     */
    @RequestMapping(value = "/changeCountBookCart", method = RequestMethod.POST, headers = {"content-type=application/json"})
    public @ResponseBody OrderJSON changeCountBookCart(@RequestBody OrderJSON correctOrder, HttpServletRequest request) {
        LOG.info("/changeCountBookCart, order = " + correctOrder);
        HttpSession session = request.getSession();
        Order order = (Order)session.getAttribute("order");
        List<Book> bookList = correctOrder.getBookList();
        Book book = bookList.get(0);
        order.getBookMap().put(book, bookList.size());
        OrderJSON orderJSON = new OrderJSON(order);
        return orderJSON;
    }

    /**
     * method called when user remove book(s) from cart
     * @param book book(s) when need to remove
     * @param request standart webapp param
     * @return correct actual order
     */
    @RequestMapping(value = "/removeBooksFromCart", method = RequestMethod.POST, headers = {"content-type=application/json"})
    public @ResponseBody OrderJSON removeBooksFromCart(@RequestBody Book book, HttpServletRequest request){
        HttpSession session = request.getSession();
        Order order = (Order)session.getAttribute("order");
        order.getBookMap().remove(book);
        return new OrderJSON(order);
    }

    /**
     * method called when user add to cart. If order is not exists - create him and store into the http session
     * @param book book which user add to cart
     * @param request standart webapp param
     * @return user order
     */
    @RequestMapping(value = "/addToCart", method = RequestMethod.POST, headers = {"content-type=application/json"})
    public @ResponseBody OrderJSON addToCart(@RequestBody Book book, HttpServletRequest request) {
        LOG.info("/addToCart, book = " + book);
        HttpSession session = request.getSession();
        Order order = (Order)session.getAttribute("order");

        //if order doesn't exist, create one
        if (order == null){
            order = new Order();
        }

        Integer countBook = new Integer(1);

        // if book is in cart, increment count book
        if (order.getBookMap().containsKey(book)){
            countBook = order.getBookMap().get(book) + 1;
        }
        order.getBookMap().put(book, countBook);
        OrderJSON newOrder = new OrderJSON(order);
        session.setAttribute("order", order);
        return newOrder;
    }

    /**
     * method called when user confirm buy. This method transfer order from session into DB
     * @param model - standart spring param
     * @param request - standart webapp param
     * @return buy view
     */
    @RequestMapping(value = "/buy", method = RequestMethod.POST)
    public String buyPost(Model model, HttpServletRequest request) {
        LOG.info("/buy, post");
        HttpSession session = request.getSession();
        Order order = (Order)session.getAttribute("order");

        //if order is empty - redirect to main page view
        if (order == null){
            return "redirect:main.htm";
        }

        orderService.createOrder(order);
        LOG.info("after create newOrder = " + order);
        session.removeAttribute("order");
        model.addAttribute("orderId", order.getOrderId());
        return "jsp/app/buy";
    }

    /**
     * called when admin go to the order-list. If user is not admin he is going to 403 access denied
     * @param model standart spring param
     * @return order list view
     */
    @RequestMapping(value = "/order-list", method = RequestMethod.GET)
    public String orderList(Model model){
        LOG.info("/order-list");
        List<Order> orderList = orderService.getOrdersForCurrentUser();
        LOG.info("orderlist = " + orderList);
        model.addAttribute("orderList", orderList);
        return "jsp/app/orderList";
    }

    /**
     * called when user go to the cart
     * @return cart view
     */
    @RequestMapping(value = "/cart", method = RequestMethod.GET)
    public String cart(){
        LOG.info("/cart");
        return "jsp/app/cart";
    }

    /**
     * called when user want to get information about order by order number
     * @param orderId - order number
     * @param model - standart spring param
     * @return find template view
     */
    @RequestMapping(value = "/findOrder", method = RequestMethod.POST)
    public String findOrder(@RequestParam String orderId, Model model){
        LOG.info("/findOrder");
        Order order = null;
        try {
            order = orderService.findOrder(Integer.parseInt(orderId));
        } catch (Exception e){
            //I do not know what should happen, but "God helps those who help themselves".
        }
        //if order not found
        if (order == null){
            model.addAttribute("findOrderId", orderId);
        }

        model.addAttribute("findOrder", order);
        return "jsp/app/template/findTemplate";
    }
}
